package com.easyUtils.utils.httpClientUtil;

import com.easyUtils.utils.httpClientUtil.config.HttpClientUtilConfig;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;

import java.io.IOException;
import java.nio.charset.StandardCharsets;


@Slf4j
public class HttpClientUtil<T> {

    //jackson序列化工具
    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static CloseableHttpClient httpClient;

    public HttpClientUtil() {
        // 创建HttpClient实例
        httpClient = new HttpClientUtilConfig().getHttpClient();
    }
    public HttpClientUtil(Integer connectSecondTimeout, Integer responseSecondTimeout, Integer connectionRequestSecondTimeout) {
        // 创建HttpClient实例
        httpClient = new HttpClientUtilConfig(connectSecondTimeout,responseSecondTimeout,connectionRequestSecondTimeout).getHttpClient();
    }

    // ------------------------------ 核心请求方法 ------------------------------

    /**
     * 发送 GET 请求。
     *
     * @param url 请求的 URL
     * @return 响应体字符串，请求失败返回 null
     * @throws IOException 如果发生 IO 错误
     * @throws ParseException 如果解析响应内容失败
     */
    public String get(String url) throws IOException, ParseException {
        log.info("正在发送 GET 请求: {}", url);
        HttpGet httpGet = new HttpGet(url);
        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("GET 请求失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取指定 URL 的内容，并返回指定类型的对象。
     *
     * @param url   请求的 URL
     * @param clazz 响应体的类型，用于反序列化
     * @param <T>   响应类型
     * @return 反序列化后的响应对象，请求失败返回 null
     * @throws IOException 如果发生 IO 错误
     */
    public <T> T get(String url, Class<T> clazz) throws IOException {
        log.info("正在发送 GET 请求: {}", url);
        HttpGet httpGet = new HttpGet(url);
        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            return objectMapper.readValue(responseBody, clazz);
        } catch (ParseException e) {
            log.error("解析响应内容失败: {}", e.getMessage(), e);
            throw new RuntimeException("解析响应内容失败", e);
        } catch (JsonProcessingException e) {
            log.error("JSON 反序列化失败: {}", e.getMessage(), e);
            throw new RuntimeException("JSON 反序列化失败", e);
        } catch (Exception e) {
            log.error("GET 请求失败: {}", e.getMessage(), e);
            return null;
        }
    }


    /**
     * 发送 POST 请求（JSON 格式请求体）。
     *
     * @param url   请求的 URL
     * @param body  请求体对象，会自动序列化为 JSON
     * @param clazz 响应体的类型，用于反序列化
     * @param <T>   响应类型
     * @return 反序列化后的响应对象，请求失败返回 null
     * @throws IOException 如果发生 IO 错误
     */
    public <T> T post(String url, Object body, Class<T> clazz) throws IOException {
        log.info("正在发送 POST 请求: {}", url);
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");

        // 将请求体序列化为 JSON
        String jsonBody = objectMapper.writeValueAsString(body);
        httpPost.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8));

        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            return objectMapper.readValue(responseBody, clazz);
        } catch (ParseException e) {
            log.error("解析响应内容失败: {}", e.getMessage(), e);
            throw new RuntimeException("解析响应内容失败", e);
        } catch (JsonProcessingException e) {
            log.error("JSON 反序列化失败: {}", e.getMessage(), e);
            throw new RuntimeException("JSON 反序列化失败", e);
        } catch (Exception e) {
            log.error("POST 请求失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 关闭 HTTP 客户端资源。
     *
     * @throws IOException 如果发生 IO 错误
     */
    public void close() throws IOException {
        log.info("正在关闭 HttpClient");
        httpClient.close();
    }


/**
 * 使用示例
 *
 * public class HttpClientUtilExample {
 *     public static void main(String[] args) {
 *         // 创建 HttpClientUtil 实例
 *         HttpClientUtil httpClient = new HttpClientUtil();
 *
 *         try {
 *             // 示例1：简单的 GET 请求
 *             String getResult = httpClient.get("https://api.example.com/users");
 *             System.out.println("GET 请求结果：" + getResult);
 *
 *             // 示例2：发送 POST 请求，传递用户对象
 *             User user = new User("张三", 25);
 *             User createdUser = httpClient.post("https://api.example.com/users", user, User.class);
 *             System.out.println("创建的用户：" + createdUser);
 *
 *             // 示例3：发送 POST 请求，处理列表响应
 *             List<Product> products = Arrays.asList(
 *                 new Product("手机", 5999.00),
 *                 new Product("电脑", 8999.00)
 *             );
 *             OrderResponse orderResponse = httpClient.post(
 *                 "https://api.example.com/orders",
 *                 products,
 *                 OrderResponse.class
 *             );
 *             System.out.println("订单响应：" + orderResponse);
 *
 *         } catch (IOException e) {
 *             System.err.println("请求发生IO异常：" + e.getMessage());
 *         } catch (ParseException e) {
 *             System.err.println("响应解析异常：" + e.getMessage());
 *         } finally {
 *             // 确保关闭资源
 *             try {
 *                 httpClient.close();
 *             } catch (IOException e) {
 *                 System.err.println("关闭客户端异常：" + e.getMessage());
 *             }
 *         }
 *     }
 * }
 */
}
